package com.example.network;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.Target;
import com.example.network.databinding.ActivityMainBinding;
import com.example.network.databinding.ActivityOkhttpMainBinding;
import com.google.gson.Gson;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class MainOkHttpActivity extends AppCompatActivity {
    private ActivityOkhttpMainBinding binding;

    // message的标识
    public final static int WEATHER_ID = 1;
    // 聚合天气预报接口地址和请求Key
    public final static String WEATHER_URL = "http://apis.juhe.cn/simpleWeather/query";
    public static String API_KEY = "8558d229e191278eaef1a355631621e4";

    // 免费天气预报接口地址
    private static final int WTHR_ID = 10;
    private static final String WTHR_URL = "http://wthrcdn.etouch.cn/weather_mini";

    private final Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            Log.i("MainActivity", msg.toString());
            if (msg.what == WEATHER_ID) {
                final Weather weather = (Weather) msg.obj;
                if (weather.getErrorCode() == 0) {
                    String result =
                            "\n当前温度：" + weather.getResult().getRealtime().getTemperature() +
                                    "\n当前天气：" + weather.getResult().getRealtime().getInfo() +
                                    "\n空气质量：" + weather.getResult().getRealtime().getAqi() +
                                    "\n明天天气：" + weather.getResult().getFuture().get(0).getWeather() +
                                    "\n明天温度：" + weather.getResult().getFuture().get(0).getTemperature() +
                                    "\n后天天气：" + weather.getResult().getFuture().get(1).getWeather() +
                                    "\n后天温度：" + weather.getResult().getFuture().get(1).getTemperature();
                    binding.tvResponse.setText(result);
                }
            } else if (msg.what == WTHR_ID) {
                Wthr wthr = (Wthr) msg.obj;
                if (wthr.getDesc().equals("OK")) {
                    String result = "\n当前温度：" + wthr.getData().getWendu() +
                            "\n当前天气：" + wthr.getData().getForecast().get(0).getType() +
                            "\n明天天气：" + wthr.getData().getForecast().get(1).getType() +
                            "\n明天高温：" + wthr.getData().getForecast().get(1).getHigh() +
                            "\n明天低温：" + wthr.getData().getForecast().get(1).getLow() +
                            "\n后天天气：" + wthr.getData().getForecast().get(2).getType() +
                            "\n后天高温：" + wthr.getData().getForecast().get(2).getHigh() +
                            "\n后天低温：" + wthr.getData().getForecast().get(2).getLow();
                    binding.tvResponse.setText(result);
                }
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityOkhttpMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        binding.btnRequest.setOnClickListener(v -> {
            // 获取图片
            GlideApp.with(MainOkHttpActivity.this)
                    .load("https://cdn.pixabay.com/photo/2020/03/31/19/20/dog-4988985__340.jpg")
                    .centerCrop()  // 居中
                    .circleCrop()  // 圆形
                    .skipMemoryCache(true)  // 关闭内存缓存
                    .diskCacheStrategy(DiskCacheStrategy.NONE) // 关闭磁盘缓存
                    .override(Target.SIZE_ORIGINAL)  // 指定尺寸
                    .placeholder(R.mipmap.ic_launcher_round)     // 临时占位符
                    .error(R.drawable.ic_error)      // 错误占位符
                    .into(binding.ivPic);
        });

        binding.btnWeather.setOnClickListener(v -> {
            String city = binding.etCity.getText().toString();
            if (!TextUtils.isEmpty(city)) {
                getWeather1(city);
            } else {
                Toast.makeText(MainOkHttpActivity.this, "请输入城市名称", Toast.LENGTH_SHORT).show();
            }
        });

        binding.btnApi.setOnClickListener(v -> {
            // get请求
            doGet("http://10.0.2.2:8080/android/hello", "");

            // post请求
            // login("http://10.0.2.2:8080/android/login", new User("android", "111111"));
        });
    }

    private void getWeather1(String city) {
        // 组合请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("city", city);
        String httpUrl = WTHR_URL + "?" + urlencode(params);
        // 获取天气数据
        final OkHttpClient client = new OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS).build();
        final Request request = new Request.Builder().url(httpUrl).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                MainOkHttpActivity.this.runOnUiThread(() -> {
                    Toast.makeText(MainOkHttpActivity.this, "出现异常：" + e.getMessage(), Toast.LENGTH_SHORT).show();
                });
            }
            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                if (response.isSuccessful() && response.body() != null) {
                    final String result = response.body().string();
                    if (!TextUtils.isEmpty(result)) {
                        // 将JSON数据转为Java对象
                        Wthr wthr = new Gson().fromJson(result, Wthr.class);
                        // handler发送消息
                        Message msg = handler.obtainMessage();
                        msg.what = WTHR_ID;
                        msg.obj = wthr;
                        handler.sendMessage(msg);
                    }
                }
            }
        });
    }

    private void login(String url, User user) {
        final Gson gson = new Gson();
        String json = gson.toJson(user);
        doPost(url, json);
    }

    private void getWeather(String city) {
        // 组合请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("city", city);
        params.put("key", API_KEY);
        String httpUrl = WEATHER_URL + "?" + urlencode(params);

        // 创建Client对象（创建机场）
        final OkHttpClient client = new OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS).build();
        // 构建者模式创建Request请求，设置url(飞去哪里）
        final Request request = new Request.Builder().url(httpUrl).build();
        // 构建Call对象（本次航班）, 发送异步请求（飞机进入就绪跑道）
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                // 异常处理（本次航班失败）
                MainOkHttpActivity.this.runOnUiThread(() -> {
                    Toast.makeText(MainOkHttpActivity.this, "出现异常：" + e.getMessage(), Toast.LENGTH_SHORT).show();
                });
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response)
                    throws IOException {
                // 处理服务器返回的数据（抵达目的地）
                if (response.isSuccessful() && response.body() != null) {
                    final String result = response.body().string();
                    if (!TextUtils.isEmpty(result) && !result.contains("超过每日可允许请求次数")) {
                        // 将JSON数据转为Java对象
                        Gson gson = new Gson();
                        Weather weather = gson.fromJson(result, Weather.class);

                        // handler发送消息
                        Message msg = handler.obtainMessage();
                        msg.what = WEATHER_ID;
                        msg.obj = weather;
                        handler.sendMessage(msg);
                    } else {
                        MainOkHttpActivity.this.runOnUiThread(() -> {
                            binding.tvResponse.setText(result);
                        });
                    }
                }
            }
        });
    }

    private Weather parseJson(String result) {
        Weather weather = new Weather();
        try {
            // 1. 第一层
            JSONObject jsonObj = new JSONObject(result);
            weather.setReason(jsonObj.getString("reason"));
            weather.setErrorCode(jsonObj.getInt("error_code"));
            // 2. 第二层
            JSONObject resultObj = jsonObj.getJSONObject("result");
            // 3. 第三层
            JSONObject realtimeObj = resultObj.getJSONObject("realtime");
            Weather.Result.Realtime realtime = new Weather.Result.Realtime();
            realtime.setTemperature(realtimeObj.getString("temperature"));
            realtime.setInfo(realtimeObj.getString("info"));
            realtime.setAqi(realtimeObj.getString("aqi"));
            // 3. 第三层
            final JSONArray futureArray = resultObj.getJSONArray("future");
            List<Weather.Result.Future> futures = new ArrayList<>();
            for (int i = 0; i < futureArray.length(); i++) {
                final JSONObject obj = futureArray.getJSONObject(i);
                Weather.Result.Future future = new Weather.Result.Future();
                future.setWeather(obj.getString("weather"));
                future.setTemperature(obj.getString("temperature"));
                futures.add(future);
            }
            Weather.Result weatherResult = new Weather.Result();
            weatherResult.setCity(resultObj.getString("city"));
            weatherResult.setFuture(futures);
            weatherResult.setRealtime(realtime);

            weather.setResult(weatherResult);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return weather;
    }

    /**
     * 将map类型转为请求参数型
     *
     * @param data Map类型参数
     * @return 请求字符串
     * http://apis.juhe.cn/simpleWeather/query?city=%E5%8D%97%E4%BA%AC&&key=
     */
    private static String urlencode(Map<String, ?> data) {
        StringBuilder builder = new StringBuilder();
        for (Map.Entry<String, ?> entry : data.entrySet()) {
            try {
                builder.append(entry.getKey()).append("=")
                        .append(URLEncoder.encode(entry.getValue() + "", "UTF-8"))
                        .append("&");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        String result = builder.toString();
        return result.substring(0, result.lastIndexOf("&"));
    }

    /**
     * GET方式的网络请求
     *
     * @param httpUrl    网址
     * @param queryParam 请求字符串，格式为key1=value1&key2=value2
     * @return 服务器端返回的字符串
     */
    private void doGet(String httpUrl, String queryParam) {
        if (!TextUtils.isEmpty(queryParam)) {
            httpUrl += "?" + queryParam;
        }
        final Request request = new Request.Builder().url(httpUrl).build();
        final OkHttpClient client = new OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                MainOkHttpActivity.this.runOnUiThread(() -> {
                    Toast.makeText(MainOkHttpActivity.this, "出现异常：" + e.getMessage(), Toast.LENGTH_SHORT).show();
                });
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                if (response.isSuccessful() && response.body() != null) {
                    String result = response.body().string();
                    if (!TextUtils.isEmpty(result)) {
                        MainOkHttpActivity.this.runOnUiThread(() -> binding.tvResponse.setText(result));

//                    Gson gson = new Gson();
//                    final ResponseEntity responseEntity = gson.fromJson(result, ResponseEntity.class);
//                    if (responseEntity != null && responseEntity.getCode() == 200) {
//                        runOnUiThread(() -> binding.tvResponse.setText((String) responseEntity.getData()));
//                    }
                    } else {
                        MainOkHttpActivity.this.runOnUiThread(() -> binding.tvResponse.setText("no data"));
                    }
                }
            }
        });
    }

    /**
     * POST方式的网络请求
     *
     * @param httpUrl 网址
     * @param param   请求字符串，格式为json字符串
     * @return 服务器端返回的字符串
     */
    private void doPost(@NonNull String httpUrl, @NonNull String param) {
        // 设置传输数据的媒体类型
        MediaType mediaType = MediaType.Companion.parse("application/json;charset=utf-8");
        // 创建请求体数据
        RequestBody body = RequestBody.Companion.create(param, mediaType);
        // POST请求
        Request request = new Request.Builder()
                .post(body)
                .url(httpUrl)
                .build();
        final OkHttpClient client = new OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                MainOkHttpActivity.this.runOnUiThread(() -> {
                    Toast.makeText(MainOkHttpActivity.this, "出现异常：" + e.getMessage(), Toast.LENGTH_SHORT).show();
                });
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                if (response.isSuccessful() && response.body() != null) {
                    String result = response.body().string();
                    if (!TextUtils.isEmpty(result)) {
                        MainOkHttpActivity.this.runOnUiThread(() -> binding.tvResponse.setText(result));
                    }
                }
            }
        });
    }
}